const rewire = require('rewire')
const config = rewire('../config.cjs')
const dto = rewire('../common/dto.cjs')
const utils = rewire('../common/utils.cjs')
const sha1 = require('sha1')
const R = require('ramda')
const {YsError} = rewire('../common/exception.cjs')
const cache = rewire('../common/cache.cjs')

function checkSignature({signature, timestamp, nonce, echostr}) {
  const now = utils.currentMs()
  if (now - timestamp * 1000 > 5 * 60 * 1000) {
    return dto.fail('请求超时')
  }
  const token = config.mpToken
  const tmpArr = [token, timestamp, nonce].sort()
  const tmpRaw = tmpArr.join('')
  const tmpStr = sha1(tmpRaw)
  if (tmpStr === signature) {
    return dto.success(echostr)
  }
  else {
    return dto.fail('签名错误')
  }
}


async function getAccessToken(appid, secret) {
  const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}`
  const {data} = await utils.httpPost(url)
  if (R.isEmpty(data['access_token'])) {
    throw new YsError('获取微信accessToken失败', 'mpError', data)
  }
  return data
}


function makeMp({appid, secret}) {
  async function autoAccessToken() {
    let at = await cache.getCache(appid + '_mp_access_token')
    if (at) {
      return at
    }
    const {access_token, expires_in} = await getAccessToken(appid, secret)
    await cache.saveCache(appid + '_mp_access_token', access_token, expires_in)
    at = await cache.getCache(appid + '_mp_access_token')
    return at
  }
  return {
    getAccessToken: autoAccessToken
  }
}


// 发送客服消息
async function sendCustomText(mp, toOpenId, msg) {
  const accessToken = await mp.getAccessToken()
  const url = `https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${accessToken}`
  const {data} = await utils.httpPost(url, {
    "touser": toOpenId,
    "msgtype":"text",
    "text":
    {
      "content": msg
    }
  })

  checkResp('sendCustomText接口调用失败', data)
}

// 拉取用户列表
async function getUserList(mp) {
  const accessToken = await mp.getAccessToken()

  async function getLeftData(nextOpenId = null) {
    let url = `https://api.weixin.qq.com/cgi-bin/user/get?access_token=${accessToken}`
    if (nextOpenId) {
      url = url + `&next_openid=${nextOpenId}`
    }

    const {data} = await utils.httpGet(url)
    checkResp('getUserList拉取用户列表失败', data)
    if (data.data.openid.length >= data.total) {
      return data.data.openid
    }
    else {
      return R.concat(data.data.openid, await getLeftData(data.next_openid))
    }
  }

  return await getLeftData()
}

function checkResp(msg, data) {
  if (data.errcode) {
    throw new YsError(msg, 'mpError', data)
  }
}

module.exports = {checkSignature, getAccessToken, makeMp, getUserList, sendCustomText}
